package com.example.umbrella;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelUuid;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.umbrella.adapter.DeviceAdapter;
import com.example.umbrella.model.BluetoothDeviceModel;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.snackbar.Snackbar;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    private static final int PERMISSION_REQUEST_CODE = 1;
    private static final int RSSI_THRESHOLD = -90;

    private long SCAN_PERIOD = 10000;
    private long SCAN_INTERVAL = 5000;

    private BluetoothAdapter bluetoothAdapter;
    private BluetoothLeScanner bluetoothLeScanner;
    private MaterialButton scanButton;
    private DeviceAdapter deviceAdapter;
    private boolean isScanning = false;
    private Handler handler = new Handler();
    private Map<String, BluetoothDeviceModel> deviceMap = new HashMap<>();
    private long lastScanStopTime = 0;

    private TextView deviceCountText;
    private View emptyView;
    private View loadingView;
    private RecyclerView deviceList;
    private View deviceListContainer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initToolbar();
        initBluetooth();
        initViews();
        checkAndRequestPermissions();
        adjustScanStrategy();
    }

    private void initToolbar() {
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setTitle("BLE扫描");
        }
    }

    private void initBluetooth() {
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        if (bluetoothManager != null) {
            bluetoothAdapter = bluetoothManager.getAdapter();
            if (bluetoothAdapter != null) {
                bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
            }
        }
    }

    private void initViews() {
        deviceList = findViewById(R.id.deviceList);
        deviceList.setLayoutManager(new LinearLayoutManager(this));
        deviceAdapter = new DeviceAdapter();
        deviceList.setAdapter(deviceAdapter);
        
        deviceAdapter.setOnItemClickListener((device) -> {
            Intent intent = new Intent(this, DeviceDetailActivity.class);
            intent.putExtra("deviceAddress", device.getDeviceAddress());
            intent.putExtra("serviceUuid", device.getServiceUuid());
            startActivity(intent);
        });

        scanButton = findViewById(R.id.scanButton);
        scanButton.setOnClickListener(v -> {
            if (!isScanning) {
                startScan();
            } else {
                stopScan();
            }
        });

        deviceCountText = findViewById(R.id.deviceCountText);
        emptyView = findViewById(R.id.emptyView);
        deviceListContainer = findViewById(R.id.deviceListContainer);
    }

    private void checkAndRequestPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            requestPermissions(
                    new String[]{
                            Manifest.permission.BLUETOOTH_SCAN,
                            Manifest.permission.BLUETOOTH_CONNECT,
                            Manifest.permission.ACCESS_FINE_LOCATION
                    },
                    PERMISSION_REQUEST_CODE
            );
        } else {
            requestPermissions(
                    new String[]{
                            Manifest.permission.ACCESS_FINE_LOCATION
                    },
                    PERMISSION_REQUEST_CODE
            );
        }
    }

    private void adjustScanStrategy() {
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = registerReceiver(null, filter);

        if (batteryStatus != null) {
            int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            float batteryPct = level * 100 / (float)scale;

            if (batteryPct < 20) {
                // 低电量模式
                SCAN_PERIOD = 5000;
                SCAN_INTERVAL = 10000;
            } else {
                // 正常模式
                SCAN_PERIOD = 10000;
                SCAN_INTERVAL = 5000;
            }
        }
    }

    private void updateUIState(boolean isScanning) {
        scanButton.setText(isScanning ? "停止扫描" : "开始扫描");
        boolean showEmptyView = !isScanning && deviceMap.isEmpty();
        emptyView.setVisibility(showEmptyView ? View.VISIBLE : View.GONE);
        loadingView.setVisibility(isScanning ? View.VISIBLE : View.GONE);
        updateDeviceCount();
    }

    private void updateDeviceCount() {
        int count = deviceMap.size();
        deviceCountText.setText(String.format("已发现 %d 个设备", count));
    }

    private void showError(String message) {
        Snackbar.make(findViewById(android.R.id.content), message, Snackbar.LENGTH_LONG)
                .setBackgroundTint(getColor(R.color.error_background))
                .setTextColor(getColor(R.color.white))
                .show();
    }

    private void startScan() {
        if (checkPermissions()) {
            isScanning = true;
            scanButton.setText("停止扫描");
            deviceAdapter.clearDevices();
            updateEmptyView();
            
            BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
            if (scanner != null) {
                scanner.startScan(scanCallback);
            }
        }
    }

    private void stopScan() {
        isScanning = false;
        scanButton.setText("开始扫描");
        
        BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
        if (scanner != null) {
            scanner.stopScan(scanCallback);
        }
    }

    private boolean checkPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN)
                    != PackageManager.PERMISSION_GRANTED) {
                showError("缺少蓝牙扫描权限");
                return false;
            }
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT)
                    != PackageManager.PERMISSION_GRANTED) {
                showError("缺少蓝牙连接权限");
                return false;
            }
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
                showError("缺少位置权限");
                return false;
            }
        } else {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
                showError("缺少位置权限");
                return false;
            }
        }
        return true;
    }

    private boolean isValidDeviceName(String name) {
        if (name == null || name.isEmpty()) {
            return false;
        }
        // 可以添加设备名称过滤逻辑
        return true;
    }

    private void saveLastConnectedDevice(String address) {
        getPreferences().edit()
                .putString("last_device", address)
                .putLong("last_connected", System.currentTimeMillis())
                .apply();
    }

    private SharedPreferences getPreferences() {
        return getSharedPreferences("BLEPreferences", MODE_PRIVATE);
    }

    private void showEnableBluetoothDialog() {
        new AlertDialog.Builder(this)
                .setTitle("开启蓝牙")
                .setMessage("扫描需要开启蓝牙，是否现在开启？")
                .setPositiveButton("开启", (dialog, which) -> {
                    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT)
                            == PackageManager.PERMISSION_GRANTED) {
                        startActivityForResult(enableBtIntent, 1);
                    }
                })
                .setNegativeButton("取消", null)
                .show();
    }

    private final ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);

            if (ActivityCompat.checkSelfPermission(MainActivity.this,
                    Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }

            int rssi = result.getRssi();
            if (rssi < RSSI_THRESHOLD) {
                return;
            }

            String deviceAddress = result.getDevice().getAddress();
            String deviceName = result.getDevice().getName();
            if (!isValidDeviceName(deviceName)) {
                deviceName = "未知设备";
            }

            List<ParcelUuid> serviceUuids = new ArrayList<>();
            if (result.getScanRecord() != null && result.getScanRecord().getServiceUuids() != null) {
                serviceUuids = result.getScanRecord().getServiceUuids();
            }

            BluetoothDeviceModel deviceModel = deviceMap.get(deviceAddress);
            if (deviceModel == null) {
                deviceModel = new BluetoothDeviceModel(deviceName, deviceAddress, rssi);
                if (!serviceUuids.isEmpty()) {
                    deviceModel.setServiceUuid(serviceUuids.get(0).toString());
                }
                deviceMap.put(deviceAddress, deviceModel);
            } else {
                if (rssi < RSSI_THRESHOLD) {
                    deviceMap.remove(deviceAddress);
                } else {
                    deviceModel.setRssi(rssi);
                    if (!serviceUuids.isEmpty()) {
                        deviceModel.setServiceUuid(serviceUuids.get(0).toString());
                    }
                }
            }

            updateDeviceList();
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            runOnUiThread(() -> {
                String errorMessage;
                switch (errorCode) {
                    case ScanCallback.SCAN_FAILED_ALREADY_STARTED:
                        errorMessage = "扫描已在进行中";
                        break;
                    case ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
                        errorMessage = "扫描注册失败";
                        break;
                    case ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED:
                        errorMessage = "设备不支持BLE扫描";
                        break;
                    default:
                        errorMessage = "扫描失败，错误码: " + errorCode;
                }
                showError(errorMessage);
                stopScan();
            });
        }
    };

    private void updateDeviceList() {
        List<BluetoothDeviceModel> deviceList = new ArrayList<>(deviceMap.values());
        deviceList.removeIf(device -> device.getRssi() < RSSI_THRESHOLD);
        Collections.sort(deviceList, (d1, d2) -> Integer.compare(d2.getRssi(), d1.getRssi()));

        runOnUiThread(() -> {
            deviceAdapter.updateDevices(deviceList);
            emptyView.setVisibility(deviceList.isEmpty() ? View.VISIBLE : View.GONE);
            updateDeviceCount();
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (bluetoothAdapter != null && !bluetoothAdapter.isEnabled()) {
            showEnableBluetoothDialog();
        }
        adjustScanStrategy();
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopScan();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopScan();
        handler.removeCallbacksAndMessages(null);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions,
                                           int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            boolean allPermissionsGranted = true;
            for (int result : grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    allPermissionsGranted = false;
                    break;
                }
            }
            if (!allPermissionsGranted) {
                showError("需要所有权限才能正常使用蓝牙功能");
            }
        }
    }

    private void updateEmptyView() {
        int deviceCount = deviceAdapter.getItemCount();
        deviceCountText.setText(String.format("已发现 %d 个设备", deviceCount));
        
        if (deviceCount == 0 && !isScanning) {
            emptyView.setVisibility(View.VISIBLE);
            deviceListContainer.setVisibility(View.GONE);
        } else {
            emptyView.setVisibility(View.GONE);
            deviceListContainer.setVisibility(View.VISIBLE);
        }
    }
}